package com.m3958.firstgwt.server.servlet;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

import javax.persistence.EntityManager;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.google.inject.Inject;
import com.google.inject.Injector;
import com.google.inject.Singleton;
import com.m3958.firstgwt.client.types.MessagePurpose;
import com.m3958.firstgwt.client.types.ServerErrorCode;
import com.m3958.firstgwt.server.dao.TokenDao;
import com.m3958.firstgwt.server.model.Group;
import com.m3958.firstgwt.server.model.Token;
import com.m3958.firstgwt.server.model.User;
import com.m3958.firstgwt.server.service.AppUtilService;
import com.m3958.firstgwt.server.service.ReqParaService;
import com.m3958.firstgwt.server.session.ErrorMessages;
import com.m3958.firstgwt.server.session.SessionUser;
import com.m3958.firstgwt.server.types.SmartError;
import com.google.inject.persist.Transactional;


@Singleton
public class TokenConsumeServlet extends HttpServlet{

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;

	
	@Inject
	private Injector injector;
	
	@Inject
	private AppUtilService autils;
	
	@Inject
	protected com.google.inject.Provider<EntityManager> emp;
	
	
	/*
	 * 1、不需要任何输出
	 * 2、输出document.write
	 * 3、输出callback
	 */
	
	@Override
	public void doGet(HttpServletRequest req, HttpServletResponse res) 
	                               throws ServletException, IOException {
		
		doPost(req, res);
	}
	
	@Override
	public void doPost(HttpServletRequest req, HttpServletResponse res) 
	                               throws ServletException, IOException {
		String uuid = req.getParameter("uuid");
		String want = req.getParameter("want");
		TokenDao tdao = injector.getInstance(TokenDao.class);
		Token t = tdao.findTokenByUuid(uuid);
		ErrorMessages errors = injector.getInstance(ErrorMessages.class);
		
		String successResult = null;
		
		if(t == null || t.isUsed()){
			errors.addError(new SmartError("该令牌已失效！", ServerErrorCode.ACCESS_DENY));
		}
		
		if(errors.isEmpty()){
			SessionUser su = injector.getInstance(SessionUser.class);
			if(MessagePurpose.INVITE_TO_GROUP.equals(t.getPurpose()) || MessagePurpose.REQUEST_JOIN_GROUP.equals(t.getPurpose())){
				try {
					if(su.getLoginStatus()){
						if(MessagePurpose.INVITE_TO_GROUP.equals(t.getPurpose())){
							User u = emp.get().find(User.class, su.getUserId());
							Group g = emp.get().find(Group.class, Integer.parseInt(t.getDetail()));
							boolean success = addToGroup(g, u,errors,t);
							if(errors.isEmpty()){
								if(success){
									successResult = autils.getListResponse(g,req.getParameter("_jsonv")).toString();
								}else{
									successResult =  autils.getEmptyListResponse().toString();
								}
							}
						}else if(MessagePurpose.REQUEST_JOIN_GROUP.equals(t.getPurpose())){
							Map<String, String> m = getDetailMap(t);
							User u = emp.get().find(User.class, Integer.parseInt(m.get("senderId")));
							Group g = emp.get().find(Group.class, Integer.parseInt(m.get("groupId")));
							boolean success = addToGroup(g, u,errors,t);
							if(errors.isEmpty()){
								if(success){
									successResult = autils.getListResponse(g,req.getParameter("_jsonv")).toString();
								}else{
									successResult =  autils.getEmptyListResponse().toString();
								}
							}
						}
					}else{
						errors.addError(new SmartError("该令牌已失效！", ServerErrorCode.ACCESS_DENY));
					}
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		}

		if(errors.isEmpty()){
			if(successResult != null){
				t.setUsed(true);
				tdao.merge(t);
				autils.writeJsonResponse(res, successResult);
			}
		}else{
			autils.writeJsonErrorResponse(res);
		}
	}
	
	
	private Map<String, String> getDetailMap(Token t){
		String[] ss = t.getDetail().split(",");
		Map<String, String> m = new HashMap<String, String>();
		for(String s:ss){
			String[] sss = s.split(":");
			m.put(sss[0], sss[1]);
		}
		return m;
	}
	
	@Transactional
	public boolean addToGroup(Group g,User u,ErrorMessages errors,Token t){
		t.setUsed(true);
		return g.manageRelation(u, true, "", errors);
	}
}
